/************************************
 * created by Tonk (tonk@ctonk.com) *
 ************************************/

// object_derived.cpp

#include "definitions.h"
#include "object.h"
#include "stringutil.h"

/////////////////////////////////////////// accessory object ///////////////////////////////////////////
Accessory::Accessory() { }

Accessory::Accessory( Accessory& it ) {
	copyObjectData( it );
}

Accessory::~Accessory() { }

Accessory& Accessory::operator = ( Accessory& it ) {
	copyObjectData( it );
	return *this;
}

void Accessory::save( std::ofstream& write ) {
	oSave( write );

	return;
}

void Accessory::load( std::ifstream& read ) {

	return;
}

void Accessory::copy( Object* base ) {

	setVnum( base->getVnum() );
	setType( base->getType() );
	setWeight( base->getWeight() );
	setFlags( base->getFlags() );
	setKeywords( base->getKeywords() );
	setShort( base->getShort() );
	setLong( base->getLong() );
	setDesc( base->getDesc() );

	return;
}

std::string Accessory::display() {
	std::string buf;

	

	buf << objectDisplay( buf );

	return buf;
}

/////////////////////////////////////////// armor object ///////////////////////////////////////////
Armor::Armor() { }

Armor::Armor( Armor& it ) {
	copyObjectData( it );
}

Armor::~Armor() { }

Armor& Armor::operator = ( Armor& it ) {
	copyObjectData( it );
	return *this;
}

void Armor::save( std::ofstream& write ) {
	oSave( write );

	return;
}

void Armor::load( std::ifstream& read ) {

	return;
}

void Armor::copy( Object* base ) {

	setVnum( base->getVnum() );
	setType( base->getType() );
	setWeight( base->getWeight() );
	setFlags( base->getFlags() );
	setKeywords( base->getKeywords() );
	setShort( base->getShort() );
	setLong( base->getLong() );
	setDesc( base->getDesc() );

	return;
}

std::string Armor::display() {
	std::string buf;

	

	buf << objectDisplay( buf );

	return buf;
}

/////////////////////////////////////////// body_part object ///////////////////////////////////////////
Body_Part::Body_Part() { }

Body_Part::Body_Part( Body_Part& it ) {
	copyObjectData( it );
}

Body_Part::~Body_Part() { }

Body_Part& Body_Part::operator = ( Body_Part& it ) {
	copyObjectData( it );
	return *this;
}

void Body_Part::save( std::ofstream& write ) {
	oSave( write );

	return;
}

void Body_Part::load( std::ifstream& read ) {

	return;
}

void Body_Part::copy( Object* base ) {

	setVnum( base->getVnum() );
	setType( base->getType() );
	setWeight( base->getWeight() );
	setFlags( base->getFlags() );
	setKeywords( base->getKeywords() );
	setShort( base->getShort() );
	setLong( base->getLong() );
	setDesc( base->getDesc() );

	return;
}

std::string Body_Part::display() {
	std::string buf;

	

	buf << objectDisplay( buf );

	return buf;
}

/////////////////////////////////////////// clothing object ///////////////////////////////////////////
Clothing::Clothing() { }

Clothing::Clothing( Clothing& it ) {
	copyObjectData( it );
}

Clothing::~Clothing() { }

Clothing& Clothing::operator = ( Clothing& it ) {
	copyObjectData( it );
	return *this;
}

void Clothing::save( std::ofstream& write ) {
	oSave( write );

	return;
}

void Clothing::load( std::ifstream& read ) {

	return;
}

void Clothing::copy( Object* base ) {

	setVnum( base->getVnum() );
	setType( base->getType() );
	setWeight( base->getWeight() );
	setFlags( base->getFlags() );
	setKeywords( base->getKeywords() );
	setShort( base->getShort() );
	setLong( base->getLong() );
	setDesc( base->getDesc() );

	return;
}

std::string Clothing::display() {
	std::string buf;

	

	buf << objectDisplay( buf );

	return buf;
}

/////////////////////////////////////////// coin object ///////////////////////////////////////////
Coin::Coin() { }

Coin::Coin( Coin& it ) {
	copyObjectData( it );
}

Coin::~Coin() { }

Coin& Coin::operator = ( Coin& it ) {
	copyObjectData( it );
	return *this;
}

void Coin::save( std::ofstream& write ) {
	oSave( write );

	return;
}

void Coin::load( std::ifstream& read ) {

	return;
}

void Coin::copy( Object* base ) {

	setVnum( base->getVnum() );
	setType( base->getType() );
	setWeight( base->getWeight() );
	setFlags( base->getFlags() );
	setKeywords( base->getKeywords() );
	setShort( base->getShort() );
	setLong( base->getLong() );
	setDesc( base->getDesc() );

	return;
}

std::string Coin::display() {
	std::string buf;

	

	buf << objectDisplay( buf );

	return buf;
}

/////////////////////////////////////////// container object ///////////////////////////////////////////
Container::Container() {
	setMaxWeight( 0 );
	setMaxSize( 0 );
}

Container::Container( Container& it ) {
	copyObjectData( it );
	setMaxWeight( it.getMaxWeight() );
	setMaxSize( it.getMaxSize() );
	for ( std::list< Object* >::iterator o_it = it.getContents().begin(); o_it != it.getContents().end(); o_it++ )
		addItem( *o_it );
}

Container::~Container() {
	getContents().clear();
}

Container& Container::operator = ( Container& it ) {
	copyObjectData( it );
	setMaxWeight( it.getMaxWeight() );
	setMaxSize( it.getMaxSize() );
	for ( std::list< Object* >::iterator o_it = it.getContents().begin(); o_it != it.getContents().end(); o_it++ )
		addItem( *o_it );
	return *this;
}

void Container::setMaxWeight( int maxWeight ) {
	_maxWeight = ( maxWeight > 0 ) ? maxWeight : 0;
	return;
}

int Container::getMaxWeight() {
	return _maxWeight;
}

void Container::setMaxSize( int maxSize ) {
	_maxSize = ( maxSize > 0 ) ? maxSize : 0;
	return;
}

int Container::getMaxSize() {
	return _maxSize;
}

std::list< Object* > Container::getContents() {
	return _contents;
}

bool Container::addItem( Object* obj ) {
	if ( canFit( obj ) ) {
		getContents().push_back( obj );
		setWeight( getWeight() + obj->getWeight() );
		return true;
	}
	return false;
}

bool Container::dropItem( std::string keywords ) {
	Object* obj = findObject( keywords );
	if ( obj != NULL ) {
		getContents().remove( obj );
		setWeight( getWeight() - obj->getWeight() );
		return true;
	}
	return false;
}

Object* Container::getItem( std::string keywords ) {
	return findObject( keywords );
}

Object* Container::findObject( std::string keywords ) {
	std::list< Object* >::iterator o_it;

	for ( o_it = getContents().begin(); o_it != getContents().end(); o_it++ )
		if ( (*o_it)->getKeywords() == keywords || str_prefix( (*o_it)->getKeywords(), keywords ) )
			return (*o_it);

	return NULL;
}

bool Container::canFit( Object* obj ) {
	if ( (unsigned)getContents().size() + (unsigned)(1 <= getMaxSize()) && getWeight() + obj->getWeight() <= getMaxWeight() )
		return true;
	return false;
}

void Container::setWeight( int weight ) {
	_weight = ( weight > 0 ) ? weight : 0;
	return;
}

int Container::getWeight() {
	return _weight;
}

void Container::addWeight( int weight ) {
	setWeight( getWeight() + weight );
	return;
}

void Container::dropWeight( int weight ) {
	setWeight( getWeight() - weight );
	return;
}

void Container::save( std::ofstream& write ) {
	oSave( write );
	std::list< Object* >::iterator it;

	write << _maxWeight << ' ' << _maxSize << '\n';
	write << "CONTENTS: " << getContents().size() << '\n';

	for ( it = getContents().begin(); it != getContents().end(); it++ )
		(*it)->save( write );

	return;
}

void Container::load( std::ifstream& read ) {
	int itemp = 0;
	char ctemp[2048];

	read >> _maxWeight >> _maxSize;
	read >> ctemp >> itemp;

	for ( int i=0; i < itemp; i++ )
		readObject( read );

	return;
}

void Container::readObject( std::ifstream& read ) {
	char ctemp[2048];
	int	vnum = 0;
	std::string type;
	int flags;
	std::string keywords;
	std::string short_desc;
	std::string long_desc;
	std::string full_desc;
	Object* obj = NULL;

	// Read base object data...
	read >> vnum >> type >> flags;
	read.get();
	read.getline( ctemp, 2048 );
	keywords = ctemp;
	read.getline( ctemp, 2048 );
	short_desc = ctemp;
	read.getline( ctemp, 2048 );
	long_desc = ctemp;
	read.getline( ctemp, 2048, '$' );
	full_desc = ctemp;

	obj = getNewObject( Object::objectType( type ) );

	obj->setVnum( vnum );
	obj->setType( Object::objectType( type ) );
	obj->setFlags( flags );
	obj->setKeywords( keywords );
	obj->setShort( short_desc );
	obj->setLong( long_desc );
	obj->setDesc( full_desc );

	if ( obj != NULL )
		obj->load( read );

	getContents().push_back( obj );

	return;
}

void Container::copy( Object* base ) {

	setVnum( base->getVnum() );
	setType( base->getType() );
	setWeight( base->getWeight() );
	setFlags( base->getFlags() );
	setKeywords( base->getKeywords() );
	setShort( base->getShort() );
	setLong( base->getLong() );
	setDesc( base->getDesc() );

	return;
}

std::string Container::display() {
	std::string buf;

	buf << "{CMax Weight:{x " << _maxWeight << '\n';
	buf << "{CMax Size:{x " << _maxSize << '\n';

	return objectDisplay( buf );
}

/////////////////////////////////////////// drink object ///////////////////////////////////////////
Drink::Drink() { }

Drink::Drink( Drink& it ) {
	copyObjectData( it );
}

Drink::~Drink() { }

Drink& Drink::operator = ( Drink& it ) {
	copyObjectData( it );
	return *this;
}

void Drink::save( std::ofstream& write ) {
	oSave( write );

	return;
}

void Drink::load( std::ifstream& read ) {

	return;
}

void Drink::copy( Object* base ) {

	setVnum( base->getVnum() );
	setType( base->getType() );
	setWeight( base->getWeight() );
	setFlags( base->getFlags() );
	setKeywords( base->getKeywords() );
	setShort( base->getShort() );
	setLong( base->getLong() );
	setDesc( base->getDesc() );

	return;
}

std::string Drink::display() {
	std::string buf;

	

	buf << objectDisplay( buf );

	return buf;
}

/////////////////////////////////////////// food object ///////////////////////////////////////////
Food::Food() { }

Food::Food( Food& it ) {
	copyObjectData( it );
}

Food::~Food() { }

Food& Food::operator = ( Food& it ) {
	copyObjectData( it );
	return *this;
}

void Food::save( std::ofstream& write ) {
	oSave( write );

	return;
}

void Food::load( std::ifstream& read ) {

	return;
}

void Food::copy( Object* base ) {

	setVnum( base->getVnum() );
	setType( base->getType() );
	setWeight( base->getWeight() );
	setFlags( base->getFlags() );
	setKeywords( base->getKeywords() );
	setShort( base->getShort() );
	setLong( base->getLong() );
	setDesc( base->getDesc() );

	return;
}

std::string Food::display() {
	std::string buf;

	

	buf << objectDisplay( buf );

	return buf;
}

/////////////////////////////////////////// furniture object ///////////////////////////////////////////
Furniture::Furniture() { }

Furniture::Furniture( Furniture& it ) {
	copyObjectData( it );
}

Furniture::~Furniture() { }

Furniture& Furniture::operator = ( Furniture& it ) {
	copyObjectData( it );
	return *this;
}

void Furniture::save( std::ofstream& write ) {
	oSave( write );

	return;
}

void Furniture::load( std::ifstream& read ) {

	return;
}

void Furniture::copy( Object* base ) {

	setVnum( base->getVnum() );
	setType( base->getType() );
	setWeight( base->getWeight() );
	setFlags( base->getFlags() );
	setKeywords( base->getKeywords() );
	setShort( base->getShort() );
	setLong( base->getLong() );
	setDesc( base->getDesc() );

	return;
}

std::string Furniture::display() {
	std::string buf;

	

	buf << objectDisplay( buf );

	return buf;
}

/////////////////////////////////////////// jewelry object ///////////////////////////////////////////
Jewelry::Jewelry() { }

Jewelry::Jewelry( Jewelry& it ) {
	copyObjectData( it );
}

Jewelry::~Jewelry() { }

Jewelry& Jewelry::operator = ( Jewelry& it ) {
	copyObjectData( it );
	return *this;
}

void Jewelry::save( std::ofstream& write ) {
	oSave( write );

	return;
}

void Jewelry::load( std::ifstream& read ) {

	return;
}

void Jewelry::copy( Object* base ) {

	setVnum( base->getVnum() );
	setType( base->getType() );
	setWeight( base->getWeight() );
	setFlags( base->getFlags() );
	setKeywords( base->getKeywords() );
	setShort( base->getShort() );
	setLong( base->getLong() );
	setDesc( base->getDesc() );

	return;
}

std::string Jewelry::display() {
	std::string buf;

	

	buf << objectDisplay( buf );

	return buf;
}

/////////////////////////////////////////// scroll object ///////////////////////////////////////////
Scroll::Scroll() { }

Scroll::Scroll( Scroll& it ) {
	copyObjectData( it );
}

Scroll::~Scroll() { }

Scroll& Scroll::operator = ( Scroll& it ) {
	copyObjectData( it );
	return *this;
}

void Scroll::save( std::ofstream& write ) {
	oSave( write );

	return;
}

void Scroll::load( std::ifstream& read ) {

	return;
}

void Scroll::copy( Object* base ) {

	setVnum( base->getVnum() );
	setType( base->getType() );
	setWeight( base->getWeight() );
	setFlags( base->getFlags() );
	setKeywords( base->getKeywords() );
	setShort( base->getShort() );
	setLong( base->getLong() );
	setDesc( base->getDesc() );

	return;
}

std::string Scroll::display() {
	std::string buf;

	

	buf << objectDisplay( buf );

	return buf;
}

/////////////////////////////////////////// trash object ///////////////////////////////////////////
Trash::Trash() { }

Trash::Trash( Trash& it ) {
	copyObjectData( it );
}

Trash::~Trash() { }

Trash& Trash::operator = ( Trash& it ) {
	copyObjectData( it );
	return *this;
}

void Trash::save( std::ofstream& write ) {
	oSave( write );

	return;
}

void Trash::load( std::ifstream& read ) {

	return;
}

void Trash::copy( Object* base ) {

	setVnum( base->getVnum() );
	setType( base->getType() );
	setWeight( base->getWeight() );
	setFlags( base->getFlags() );
	setKeywords( base->getKeywords() );
	setShort( base->getShort() );
	setLong( base->getLong() );
	setDesc( base->getDesc() );

	return;
}

std::string Trash::display() {
	std::string buf;

	

	buf << objectDisplay( buf );

	return buf;
}

/////////////////////////////////////////// wand object ///////////////////////////////////////////
Wand::Wand() { }

Wand::Wand( Wand& it ) {
	copyObjectData( it );
}

Wand::~Wand() { }

Wand& Wand::operator = ( Wand& it ) {
	copyObjectData( it );
	return *this;
}

void Wand::save( std::ofstream& write ) {
	oSave( write );

	return;
}

void Wand::load( std::ifstream& read ) {

	return;
}

void Wand::copy( Object* base ) {

	setVnum( base->getVnum() );
	setType( base->getType() );
	setWeight( base->getWeight() );
	setFlags( base->getFlags() );
	setKeywords( base->getKeywords() );
	setShort( base->getShort() );
	setLong( base->getLong() );
	setDesc( base->getDesc() );

	return;
}

std::string Wand::display() {
	std::string buf;

	

	buf << objectDisplay( buf );

	return buf;
}

/////////////////////////////////////////// weapon object ///////////////////////////////////////////
Weapon::Weapon() { }

Weapon::Weapon( Weapon& it ) {
	copyObjectData( it );
}

Weapon::~Weapon() { }

Weapon& Weapon::operator = ( Weapon& it ) {
	copyObjectData( it );
	return *this;
}

void Weapon::save( std::ofstream& write ) {
	oSave( write );

	return;
}

void Weapon::load( std::ifstream& read ) {

	return;
}

void Weapon::copy( Object* base ) {

	setVnum( base->getVnum() );
	setType( base->getType() );
	setWeight( base->getWeight() );
	setFlags( base->getFlags() );
	setKeywords( base->getKeywords() );
	setShort( base->getShort() );
	setLong( base->getLong() );
	setDesc( base->getDesc() );

	return;
}

std::string Weapon::display() {
	std::string buf;

	

	buf << objectDisplay( buf );

	return buf;
}
